package passwordchecker;

public class PasswordChecker02 extends sequencia {

        public final String sAlphas = "abcdefghijlmnopqrstuvwxyz";
        public final String sNumerics = "01234567890";
        public final String sSymbols = ")!@#$%^&*()";
        
    
    public void checkPassword(String pwd) {
        int nScore = 0, nLength = 0, nAlphaUC = 0, nAlphaLC = 0, nNumber = 0, nSymbol = 0, nMidChar = 0,
                nRequirements = 0, nAlphasOnly = 0, nNumbersOnly = 0, nUnqChar = 0, nRepChar = 0,
                nConsecAlphaUC = 0, nConsecAlphaLC = 0, nConsecNumber = 0, nConsecSymbol = 0,
                nConsecCharType = 0, nSeqAlpha = 0, nSeqNumber = 0, nSeqSymbol = 0, nSeqChar = 0,
                nReqChar = 0;
        double nRepInc = 0.0;
      
        int  nMultConsecAlphaUC = 2, nMultConsecAlphaLC = 2,
                nMultConsecNumber = 2;
        int  nMultSeqAlpha = 3, nMultSeqNumber = 3,
                nMultSeqSymbol = 3;
        int nMultLength = 4, nMultNumber = 4;
        int nMultSymbol = 6;
        int nTmpAlphaUC = -1, nTmpAlphaLC = -1, nTmpNumber = -1, nTmpSymbol = -1;
        String sAlphaUC = "0", sAlphaLC = "0", sNumber = "0", sSymbol = "0",  sRequirements = "0",
                sAlphasOnly = "0", sNumbersOnly = "0", sRepChar = "0", sConsecAlphaUC = "0", sConsecAlphaLC = "0",
                sConsecNumber = "0", sSeqAlpha = "0", sSeqNumber = "0", sSeqSymbol = "0";
        
        int nMinPwdLen = 8;

        score1 buscaComplex = new score1();
        sequencia2 seqBonusBusca = new sequencia2();
        sequencia sequenciaBusca = new sequencia();

        if (pwd != null && !pwd.equals("")) {
            nScore = pwd.length() * nMultLength;
            nLength = pwd.length();
            char[] pwd2 = pwd.replaceAll("\\s+", "").toCharArray();
            int arrPwdLen = pwd2.length;

            for (int i = 0; i < arrPwdLen; i++) {
                if (Character.isLetter(pwd2[i]) && Character.isUpperCase(pwd2[i])) {
                    if (nTmpAlphaUC != -1) {
                        if ((nTmpAlphaUC + 1) == i) {
                            nConsecAlphaUC++;
                            nConsecCharType++;
                        }
                    }
                    nTmpAlphaUC = i;
                    nAlphaUC++;
                } else if (Character.isLetter(pwd2[i]) && Character.isLowerCase(pwd2[i])) {
                    if (nTmpAlphaLC != -1) {
                        if ((nTmpAlphaLC + 1) == i) {
                            nConsecAlphaLC++;
                            nConsecCharType++;
                        }
                    }
                    nTmpAlphaLC = i;
                    nAlphaLC++;
                } else if (Character.isDigit(pwd2[i])) {
                    if (i > 0 && i < (arrPwdLen - 1)) {
                        nMidChar++;
                    }
                    if (nTmpNumber != -1) {
                        if ((nTmpNumber + 1) == i) {
                            nConsecNumber++;
                            nConsecCharType++;
                        }
                    }
                    nTmpNumber = i;
                    nNumber++;
                } else if (!Character.isDigit(pwd2[i]) && !Character.isLetter(pwd2[i]) && pwd2[i] != '_') {
                    if (i > 0 && i < (arrPwdLen - 1)) {
                        nMidChar++;
                    }
                    if (nTmpSymbol != -1) {
                        if ((nTmpSymbol + 1) == i) {
                            nConsecSymbol++;
                            nConsecCharType++;
                        }
                    }
                    nTmpSymbol = i;
                    nSymbol++;
                }

                boolean bCharExists = false;
                for (int b = 0; b < arrPwdLen; b++) {
                    if (pwd2[i] == pwd2[b] && i != b) {
                        bCharExists = true;
                        nRepInc += Math.abs((double) arrPwdLen / (b - i));
                    }
                }
                if (bCharExists) {
                    nRepChar++;
                    nUnqChar = arrPwdLen - nRepChar;
                    nRepInc = (nUnqChar != 0) ? (int) Math.ceil(nRepInc / nUnqChar) : (int) Math.ceil(nRepInc);
                }
            }

            for (int s = 0; s < 22; s++) {
                String sFwd = sAlphas.substring(s, s + 3);
                String sRev = new StringBuffer(sFwd).reverse().toString();
                if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) {
                    nSeqAlpha++;
                    nSeqChar++;
                }
            }

            for (int s = 0; s < 8; s++) {
                String sFwd = sNumerics.substring(s, s + 3);
                String sRev = new StringBuffer(sFwd).reverse().toString();
                if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) {
                    nSeqNumber++;
                    nSeqChar++;
                }
            }

            for (int s = 0; s < 8; s++) {
                String sFwd = sSymbols.substring(s, s + 3);
                String sRev = new StringBuffer(sFwd).reverse().toString();
                if (pwd.toLowerCase().indexOf(sFwd) != -1 || pwd.toLowerCase().indexOf(sRev) != -1) {
                    nSeqSymbol++;
                    nSeqChar++;
                }
            }

            System.out.println("nLengthBonus is: + " + nScore);

            // Foram criadas 2 classes a mais para simplificar o código

            seqBonusBusca.sequenciaBonus1(nAlphaUC, nLength, nScore, sAlphaUC);
            seqBonusBusca.sequenciaBonus2(nAlphaLC, nLength, nScore, sAlphaLC);
            seqBonusBusca.sequenciaBonus3(nNumber, nLength, nScore, nMultNumber, sNumber);
            seqBonusBusca.sequenciaBonus4(nSymbol, nScore, nMultSymbol, sSymbol);
            sequenciaBusca.sequencia8(nAlphaLC, nAlphaUC, nSymbol, nNumber, nScore, nLength, nAlphasOnly, sAlphasOnly);
            sequenciaBusca.sequencia9(nAlphaLC, nAlphaUC, nSymbol, nNumber, nScore, nLength, nNumbersOnly, sNumbersOnly);
            sequenciaBusca.sequencia1(nRepChar, nScore, nRepChar, sRepChar);
            sequenciaBusca.sequencia2(nScore, nConsecAlphaUC, nMultConsecAlphaUC, sConsecAlphaUC);
            sequenciaBusca.sequencia3(nConsecAlphaLC, nScore, nMultConsecAlphaLC, sConsecAlphaLC);
            sequenciaBusca.sequencia4(nConsecNumber, nScore, nMultConsecNumber, sConsecNumber);
            sequenciaBusca.sequencia5(nSeqAlpha, nScore, nMultSeqAlpha, sSeqAlpha);
            sequenciaBusca.sequencia6(nSeqNumber, nScore, nMultSeqNumber, sSeqNumber);
            sequenciaBusca.sequencia7(nSeqSymbol, nScore, nMultSeqSymbol, sSeqSymbol);
            // linha abaixo criada a partir da refatoração
            nReqChar = buscaComplex.retornaInteiro(nLength, nAlphaUC, nAlphaLC, nNumber, nSymbol, nMinPwdLen, nReqChar);
            
            nRequirements = nReqChar;
            // Esta funcao alem de fazer calculos a mesma imprime os dados
            buscaComplex.requerimento(pwd, nMinPwdLen, nRequirements, nScore, sRequirements);
            
            System.out.println("Strength score is: " + nScore + "%");
            buscaComplex.complexidade(nScore);
        } else {
            System.out.println("Strength score is:" + nScore + "%");
            buscaComplex.complexidade(nScore);
        }
    }
}